قطاع الإنطلاق Boot Sector

(الجزء 1)

بسم الله الرحمن الرحيم

برمجة نظام التشغيل ككل مسار تطوير عنده بداية. لكن أجمل ما في هذه البداية أنها تتطابق مع بداية تشغيل الحاسب. إذ أن أول جزء يطور من نظام التشغيل هو قطاع الإنطلاق. الذي يعتبر أول برنامج ينفذ في نظام التشغيل بعد ال Bios.

ما هو قطاع الانطلاق ؟

قطاع الانطلاق هو ملف حجمه 512 byte. يكتب في أول قطاع من قرص مرن ، قرص صلب أو قسم (Partition) من قرص الصلب .و يمكن وضعه في خادم (Server) لكي ينطلق بواسطته جهاز مستخدم (Client).

يحتوي قطاع الانطلاق على ثلاثة أقسام :

مراحل انطلاق الحاسب:

1) بعد الضغط على زر تشغيل الحاسب يقوم هذا الأخير بتنفيذ برنامج ال Bios الموجود في ذاكرة ROM . يكون التنفيذ بعد نسخ ال Bios من الذاكرة ROM إلى الذاكرة المركزية RAM.

2) برنامج ال Bios يقوم بإعداد بياناته الداخلية و بالتحقق من سلامة المعدات و الأجهزة و تسمى هذه العملية بـ POST
(Power On Self Test). ثم يبحث في قائمة الدعامات التي تحتوي على قطاع الانطلاق . هذه القائمة قد تحتوي مثلا على:

ترتيب الدعامة اسم الدعامة شرح
1 floppy أول قرص المرن  (:a)
2 IDE0 أول قرص صلب (:c)
3 CDROM

أول قرص مضغوط

3) يقرأ القطاع من أول دعامة متوفرة و يتأكد من وجود توقيع الصلاحية. إذا وجد التوقيع الصحيح يقوم بتحميل القطاع إلى العنوان 0000:7C00 و الموافق للعنوان المادي 0x7C00 .

4) يضع ال Bios رمز الدعامة التي تم تحميل القطاع منها في السجل DL. رموز بعض الدعامات هي:

الدعامة رمزها
القرص مرن رقم 1 0x00
القرص الصلب رقم 1 0x80
القرص الصلب رقم 2 0x81

5) في النهاية يقوم ال Bios بقفز طويل (long jump) نحو العنوان 0000:7C00 بغرض تنفيذ البرنامج الموجود في قطاع الانطلاق.
هذا الجدول يلخص محتوى السجلات قبل تنفيذ برنامج قطاع الانطلاق:

السجلات المحتوى
DL رمز دعامة الانطلاق
CS 0x0000 و هو عنوان قسم التعليمات الجديد.
IP 0x7C00 و هو قيمة الانتقال داخل قسم التعليمات
جميع السجلات الأخرى محتوى غير معرف

6) هنا يأتي دور قطاع الانطلاق للتحكم في الحاسب.

كتابة أول قطاع انطلاق:

سنحاول الآن إن شاء الله كتابة قطاع انطلاق بسيط يكتب جملة "! Salam Alikom" ( "السلام عليكم" ) ثم يتوقف.

يجب أن نلاحظ أولا أن السجلات IP CS DL هي الوحيدة التي تحتوي على قيم معرفة. لكننا نحتاج إلى وسط تنفيذي لبرنامج قطاع الانطلاق.
يتكون الوسط التنفيذي من:

في ما يخص DS و ES يكفي اختيار القسم 07C0:0000 أي أن ES = DS = 0x07C0 . و هو نفسه العنوان 0000:7C00 .
أما الكومة فتختارها تبدأ في العنوان 9000:0000 أي أن SS = 0x9000 و نختار SP = 0xFFFF لنحصل على كومة بحجم 64kb.

هذا الرسم يلخص تقسيم الذاكرة المناسب للوسط التنفيذي لبرنامج قطاع الانطلاق:

بعد توفير الوسط التنفيذي نقوم برسم جملة "! Salam Alikom".
لا نستطيع استعمال الوظيفة 9h للانقطاع 21h لأنها خاصة بنظام التشغيل MS-DOS بل سنكتب إجراء صغير يرسم الجمل ويعتمد على الوظيفة 0Eh من الانقطاع 10h الخاص بال Bios. هذه الوظيفة ترسم حرف واحد على الشاشة. الجدول التالي يصف هذه الوظيفة.

محتوى السجلات عند مناداة الانقطاع

الوصف

السجل

رقم الوظيفة و هو 0Eh.

AH = 0Eh

رمز الحرف في نظام الترميز ASCII.

AL

لون الحرف.

BL

النتائج

لا شيء

و في النهاية نوقف البرنامج بواسطة دوران غير منتهي. و هذا بالقفز إلى نفس البطاقة ( Label ).

البرنامج النهائي مكتوب بصيغة NASM و هو الملف boot.s . هذا هو محتواه:

[BITS 16]
 
استعمال تعليمات بحجم 16 bit.
 
EntryPoint: بداية برنامج قطاع الانطلاق.
     mov ax,07c0h
     mov ds,ax
     mov es,ax
 
تحضير الوسط التنفيذي لبرنامج قطاع الانطلاق. نضع في السجلين DS و ES رقم القسم 0x07C0 عن طريق السجل AX.
العنوان 07C0:0000 يمثل مكان وجود ملف قطاع  الانطلاق في الذاكرة.

 
     mov ax,09000h
     mov ss,ax
التصريح بكومة تبدأ قاعدتها من القسم 0x9000.
     mov sp,0ffffh
 
وضع العدد 0xFFFF في SP للحصول على كومة بحجم 64kb.
     mov si,Salam
     call ShowMsg
نضع في السجل SI قيمة انتقال الجملة "! Salam Alikom" داخل قسم البيانات.
مناداة إجراء رسم الجمل.
k_loop:
     jmp k_loop

 

حلقة مفرغة تهدف فقط إلى توقيف البرنامج.


 
ShowMsg: بداية الإجراء ShowMsg (رسم جملة).
     push ax
     push bx
حفظ السجلين AX و BX في الكومة لأنهما سيستعملان في الإجراء.
 
.loop_start:
     lodsb
بداية حلقة تعليمات رسم جملة.
و ضع Byte من العنوان [DS:SP] في السجل
al. ( هو رمز الحرف المراد رسمه ).
     cmp al,0
     je .loop_end
التحقق من عدم نهاية الجملة بالعدد 0.
في حالة al = 0 نقفز إلى نهاية حلقة التعليمات.
     mov ah,0Eh اختيار وظيفة رسم حرف ( الوظيفة رقم 0xE التابعة للانقطاع 0x10).
     mov bx,07h اختيار اللون الأبيض.
     int 10h مناداة الانقطاع 0x10 الخاص بال Bios.
     jmp .loop_start القفز إلى بداية حلقة التعليمات.
.loop_end: نهاية حلقة التعليمات.
     pop bx
     pop ax
استرجاع قيم AX و BX.
 
     ret

 
نهاية إجراء رسم الجمل. و العودة إلى المنادي.

 
Salam db "Salam Alikom !",13,10,0

 
التصريح بالجملة المراد كتابتها على الشاشة.

 
times 510-($-$$) db 0

 
التصريح بـ: 510-($-$$) Byte ذات القيمة 0 للحصول على 512 Byte في الملف المنتج و هو حجم قطاع انطلاق.
$ : يرمز إلى مكان العبارة (Expression) الحالية داخل الملف الذي سينتج.
$$ : يرمز إلى بداية القطعة (Section) الحالية من الملف الذي سينتج.
DW 0AA55h التصريح بتوقيع الصلاحية (Bios Boot Signature).

لصناعة قطاع الانطلاق نكتب الأمر التالي في سطر الأوامر (Command Line - Shell):

nasm -f bin -o boot boot.s

هذا الأمر يصنع الملف boot ذو الحجم 512 Byte.
التوجيه "o boot-" يأمر Nasm بصناعة ملف اسمه "boot" . أما التوجيه "f bin-" فتأمر Nasm بصناعة ملف خالي من كل معلومات إضافية بل يحتوي فقط على تعليمات البرنامج مع بياناته.

كتابة قطاع الانطلاق على القرص المرن:

لتجربة قطاع الانطلاق الذي كتبناه يكفي كتابته في أول قطاع من قرص المرن ثم إعادة تشغيل الجهاز لينطلق من هذا القرص.
ضع قرص مرن في قارئ القرص المرن. (كل الملفات الموجودة فيه ستفقد).

dd if=boot of=/dev/fd0
write

الآن اعد تشغيل الجهاز. سينطلق الجهاز هذه المرة من القرص المرن و يكتب الجملة "! Salam Alikom".

يمكنك الآن القول بأنك قمت بخطوة صغيرة جدا و لكنها مهمة في طريق برمجة نظام تشغيل. الحمد لله.
 

الملف"boot.s":

[BITS 16]

EntryPoint:
      mov ax,07c0h
      mov ds,ax
      mov es,ax

      mov ax,09000h
      mov ss,ax
      mov sp,0ffffh

      mov si,Salam
      call ShowMsg

k_loop:
      jmp k_loop

ShowMsg:
      push ax
      push bx
.loop_start:
      lodsb
      cmp al,0
      je .loop_end
      mov ah,0Eh
      mov bx,07h
      int 10h
      jmp .loop_start
.loop_end:
      pop bx
      pop ax
      ret



      Salam db "Salam Alikom !",13,10,0

      times 510-($-$$) db 0

      DW 0AA55h
 


الملف"write.s":

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; file : write.s
;
; Synopsis:
; --------
; This small program writes a file named "boot" on the first sector
; of a floppy, commonly known as the boot sector.
;
; To produce the com file "write.com" , type :
; nasm -f bin -o write.com write.s
;
; Author: Hamoud Mourad
; hmdz@alkhawarezmi.com
;
; Visit: www.alkhawarezmi.com
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


[bits 16]

org 100h

section .text

start:
      ; open a file
      mov ax,0x3D40
      mov dx,file_name
      int 21h

      jc error1

      ; save file handle
      mov [handle],ax

      mov dx,msg_ok1
      call show_msg

read_file:
      mov ah,0x3F
      mov bx,[handle]
      mov cx,512
      mov dx,buffer
      int 21h

      jc error2

      cmp ax,512
      jne error2

      write_boot:
      mov ah,0
      mov dl,0
      int 13h

      mov ax,ds
      mov es,ax
      mov ax,0x0301
      xor dx,dx
      mov cx,0x0001
      mov bx,buffer
      int 13h

      jc error3

      mov dx,msg_ok2
      call show_msg

close_file:
      ; close the file
      mov ah,0x3E
      mov bx,[handle]
      int 21h

exit:
      mov ax,0x4c00
      int 21h

error1:
      mov dx,msg_error1
      call show_msg
      call exit

error2:
      mov dx,msg_error2
      call show_msg
      call close_file

error3:
      mov dx,msg_error3
      call show_msg
      call close_file

show_msg:
      push ax
      mov ah,0x09
      int 21h
      pop ax
      ret

section .data
      file_name db "boot",0
      msg_ok1 db "file : boot --> opened",13,10,'$'
      msg_ok2 db "file : boot written on floppy successfully",13,10,'$'
      msg_error1 db "failed to open file : boot",13,10,'$'
      msg_error2 db "can't read 512 byte from file : boot",13,10,'$'
      msg_error3 db "can't write 512 byte on floppy",13,10,'$'

section .bss
      buffer resb 512
      handle resw 1
 

هذا الملف هو برنامج المصدر لـ: "write.com".
لصناعة الملف "write.com" نكتب في سطر الأوامر :

nasm -f bin -o write.com write.s

 

الكاتب : مراد حمود

التاريخ : 13/12/2004